const jsSHA = require('jssha')
const { accessTokenExpired } = require('./utils')
const tokenStore = require('./tokenStore')
const services = require('./services')

let jsapiTicketStore = null
function getJsApiTicket (appid, secret) {
  console.log('=====> jsapiTicketStore ===')
  if (!accessTokenExpired(jsapiTicketStore, 'ticket')) {
    console.log('store in memory')
    return Promise.resolve(jsapiTicketStore.ticket)
  }

  console.log('from wechat server')

  return tokenStore.getAccessToken(appid, secret)
    .then(access_token => services.getJsApiTicket(access_token))
    .then(response => {
      const { errcode, errmsg } = response

      if (errcode && errmsg) {
        throw new Error(errmsg)
      }

      console.log('jsapiTicketStore', response)
      save(response)
      return response.ticket
    })
}

function save (store) {
  jsapiTicketStore = Object.assign(
    {},
    store,
    { expires_in: ~~(new Date().getTime() / 1000) + store.expires_in /* seconds */ }
  )
}

const createNonceStr = ()  => {
  return Math.random().toString(36).substr(2, 15);
};

const createTimestamp = () => {
  return parseInt(new Date().getTime() / 1000) + '';
};

const raw = (args) => {
  var keys = Object.keys(args);
  keys = keys.sort()
  var newArgs = {};
  keys.forEach(function (key) {
    newArgs[key.toLowerCase()] = args[key];
  });

  var string = '';
  for (var k in newArgs) {
    string += '&' + k + '=' + newArgs[k];
  }
  string = string.substr(1);
  return string;
};

/**
* @synopsis 签名算法
*
* @param jsapi_ticket 用于签名的 jsapi_ticket
* @param url 用于签名的 url ，注意必须动态获取，不能 hardcode
*
* @returns
*/
function sign (jsapi_ticket, url) {
  var ret = {
    jsapi_ticket: jsapi_ticket,
    nonceStr: createNonceStr(),
    timestamp: createTimestamp(),
    url: url
  }
  var string = raw(ret)
  var shaObj = new jsSHA('SHA-1', 'TEXT')

  shaObj.update(string)
  ret.signature = shaObj.getHash('HEX')

  return ret
}

module.exports = {
  getJsApiTicket: getJsApiTicket,
  sign: sign
}
